ELF（5）Linux　程序员手册　ELF（5）



名称
       elf - 可执行和链接格式（Executable and Linking Format）文件

概要
       #include <elf.h>

描述
        头文件<elf.h>定义了ELF可执行二进制文件的格式。这些文件包括常见的可执行文件以
        及可重定位文件、内核文件、动态共享库文件。

        一个可执行连接文件包含ELF头接着是一个程序头表或者节头表，或者两者都有。可执行
        连接文件的ELF头数据从文件数据的起始位置开始。程序头表以及节头表在文件中的偏移
        位置在ELF头中定义。这两个表详细描述了ELF文件特征。

        以上提到的头文件 <elf.h> 将ELF文件组织为c语言结构体以包括动态节、重定位节、
        符号表。

        以下类型用于N位体系结构（N = 32,64，ElfN 代表 Elf32 或 Elf64，uintN_t表示
        uint32_t或uint64_t）：

        ElfN_Addr 无符号程序地址，uintN_t，（Elf32_Addr：4字节， Elf64_Addr：8字节）
        ElfN_Off 无符号文件偏移量，uintN_t，（Elf32_Addr：4字节， Elf64_Addr：8字节）
        ElfN_Section 			无符号节索引，uint16_t
        ElfN_Versym				无符号版本符号信息，uint16_t
        Elf_Byte 				无符号字节
        ElfN_Half uint16_t
        ElfN_Sword int32_t
        ElfN_Word uint32_t
        ElfN_Sxword int64_t
        ElfN_Xword uint64_t

        （注：* BSD术语有所不同，有Elf64_Half两倍于Elf32_Half大小的，然后
        Elf64Quarter用于表示uint16_t。为了避免混淆，下面将对这些类型进行特别说明。）

        文件格式定义的所有数据结构遵循相关类型的“原生”大小和对齐准则。 如有需要，
       	将对数据结构进行显式填充，将数据结构大小强制调整为4的倍数，以确保4字节对象保
       	持4字节对齐等等。

       	ELF标头由Elf32_Ehdr或Elf64_Ehdr结构描述：

       	#define EI_NIDENT 16

       	typedef struct {
           unsigned char e_ident[EI_NIDENT];
           uint16_t      e_type;
           uint16_t      e_machine;
           uint32_t      e_version;
           ElfN_Addr     e_entry;
           ElfN_Off      e_phoff;
           ElfN_Off      e_shoff;
           uint32_t      e_flags;
           uint16_t      e_ehsize;
           uint16_t      e_phentsize;
           uint16_t      e_phnum;
           uint16_t      e_shentsize;
           uint16_t      e_shnum;
           uint16_t      e_shstrndx;
       	} ElfN_Ehdr;

       头文件<elf.h>定义了ELF可执行二进制文件的格式。这些文件是常见的可执行文件
       文件，可重定位对象文件，核心文件和共享库。

       ELF文件由ELF头，后跟程序头表或节表头或两者都有。 ELF头总是在文件的最开始部分。
       程序头表和节表头在文件中的偏移量在ELF头中定义。这两个表格描述了文件的其余的特
       征。

       上述头文件<elf.h>被描述为C结构，包括动态节结构、重定位表和符号表。

       以下类型用于描述N位体系结构（N = 32,64，ElfN表示Elf32或Elf64，uintN_t表示
       uint32_t或uint64_t）：

           ElfN_Addr       无符号程序地址, uintN_t
           ElfN_Off        无符号文件偏移量, uintN_t
           ElfN_Section    无符号节索引, uint16_t
           ElfN_Versym     无符号版本符号信息, uint16_t
           Elf_Byte        无符号字节
           ElfN_Half       uint16_t
           ElfN_Sword      int32_t
           ElfN_Word       uint32_t
           ElfN_Sxword     int64_t
           ElfN_Xword      uint64_t

        （注意：* BSD术语有点不同，Elf64_Half是Elf32_Half的两倍，Elf64Quarter表示
        	uint16_t。为了避免混淆，下面将对这些类型进行详述）

        文件格式定义的所有数据结构遵循相关类型的“自然”大小和对齐准则。
       	如果需要，对数据结构进行显式填充，以确保4字节对象的4字节对齐，强制结构尺寸
       	为4字节的倍数等。

       	ELF标头由Elf32_Ehdr或Elf64_Ehdr类型描述：

       		#define EI_NIDENT 16

           	typedef struct {
               unsigned char e_ident [EI_NIDENT];
               uint16_t e_type;
               uint16_t e_machine;
               uint32_t e_version;
               ElfN_Addr e_entry;
               ElfN_Off e_phoff
               ElfN_Off e_shoff;
               uint32_t e_flags;
               uint16_t e_ehsize;
               uint16_t e_phentsize;
               uint16_t e_phnum;
               uint16_t e_shentsize;
               uint16_t e_shnum;
               uint16_t e_shstrndx;
           	} ElfN_Ehdr;

         这些字段具有以下含义：

       	e_ident     这个字节数组指定解释文件，独立于处理器或文件的其他内容。在这个字
       	节数组中，大部分内容都是以EI_为前缀的宏定义，可能还包含其他以ELF为前缀的宏。
       	宏定内容义如下：

	       	EI_MAG0     魔数的第一个字节。必须填充ELFMAG0。 （0：0x7f）

	       	EI_MAG1  	魔数的第二个字节。必须填充ELFMAG1。 （1：'E'）

	       	EI_MAG2   	魔数的第三个字节。必须填充ELFMAG2。 （2：'L'）

	       	EI_MAG3  	魔数的第四个字节。必须填充ELFMAG3。 （3：'F'）

	       	EI_CLASS  	第五个字节标识此二进制文件的体系结构：

	       		ELFCLASSNONE 	此类无效。
	            ELFCLASS32		这定义了32位架构。它支持文件和虚拟地址空间高达4G字节。
	            ELFCLASS64  	这定义了64位架构。

	        EI_DATA  	第六个字节指定文件数据编码格式。目前支持以下编码：

	        	ELFDATANONE  	未知数据格式。
	           	ELFDATA2LSB  	二进制补码，小端。
	           	ELFDATA2MSB  	二进制补码，大端。

	        EI_VERSION  	第七个字节是ELF规范的版本号：
	           	EV_NONE 版本无效。
	           	EV_CURRENT 当前版本。

	        EI_OSABI  	第八个字节标识对象所针对的操作系统和ABI。其他具有标志和值ELF
	        结构的字段具有平台特定含义，这些字段的解释由该字节的值决定。例如：

	        	ELFOSABI_NONE  		与ELFOSABI_SYSV相同
				ELFOSABI_SYSV  		UNIX系统V ABI。
				ELFOSABI_HPUX  		HP-UX ABI。
				ELFOSABI_NETBSD 	NetBSD ABI。
				ELFOSABI_LINUX  	Linux ABI。
				ELFOSABI_SOLARIS  	Solaris ABI。
				ELFOSABI_IRIX  		IRIX ABI。
				ELFOSABI_FREEBSD  	FreeBSD ABI。
				ELFOSABI_TRU64  	TRU64 UNIX ABI。
				ELFOSABI_ARM 		ARM体系结构ABI。
				ELFOSABI_STANDALONE	独立（嵌入式）ABI。

			EI_ABIVERSION
				第九个字节标识对象所针对的ABI的版本。这个字段是用于区分ABI的不兼容版
				本。该版本号的解释取决于EI_OSABI字段识别的ABI。符合这一点的应用规格
				使用值0。

			EI_PAD  	开始填充。这些字节被保留并设置为零。解析程序应该忽略他们。如
			果当前未使用的字节被给予特殊意义，EI_PAD的值将在以后更改。

			EI_NIDENT e_ident数组的大小。

		e_type  	该结构的这个成员标识对象文件类型：

			ET_NONE  	未知类型。
			ET_REL  	可重定位文件。
			ET_EXEC  	可执行文件。
			ET_DYN  	共享对象文件。
			ET_CORE  	核心文件。

		e_machine	此成员为文件指定所需的体系结构。例如：

			EM_NONE		未知的机器。
			EM_M32 		AT＆T WE 32100。
			EM_SPARC 	Sun Microsystems SPARC。
			EM_386 		Intel 80386。
			EM_68K		Motorola 68000.
			EM_88K		Motorola 88000.
			EM_860 		Intel 80860。
			EM_MIPS 	MIPS RS3000（仅限big-endian）。
			EM_PARISC 	HP / PA。
			EM_SPARC32PLUS
			       		具有增强的指令集的SPARC。
			EM_PPC 		PowerPC。
			EM_PPC64 	PowerPC 64位。
			EM_S390 	IBM S / 390
			EM_ARM		高级RISC机
			EM_SH		Renesas SuperH
			EM_SPARCV9 	SPARC v9 64位。
			EM_IA_64 	Intel Itanium
			EM_X86_64 	AMD x86-64
			EM_VAX 		DEC Vax。

		e_version此成员标识文件版本：

           	EV_NONE		版本无效。
           	EV_CURRENT	当前版本。

        e_entry		执行该程序的入口点。如果文件没有入口点，则该成员保持为零。

        e_phoff		该成员保存程序头表在文件中偏移量（以字节为单位）。如果文件没有程
        序头表，该成员持有零。

        e_shoff		该成员保存节头表在文件中偏移量（以字节为单位）。如果文件没有段
        头表该成员保持为零。

    e_flags  	此成员保存与文件关联的特定处理器的标志。标志名称采取EF_`machine_flag'
    的形式。目前没有定义任何标志。

    e_ehsize 	此成员保存ELF头的大小（以字节为单位）。

    e_phentsize		该成员保存文件程序头表中每一个项的大小（以字节为单位）所有项都
    相同尺寸。

    e_phnum 	该成员保存程序头表中的项数。因此e_phentsize和e_phnum给出了程序头表
    的大小（以字节为单位）。如果文件没有程序头，e_phnum保持值为零。

    			如果程序头表中的项数大于或等于PN_XNUM（0xffff），则该成员
               	保持PN_XNUM（0xffff），程序头表中的实际数目保存在节头表的sh_info成员
               	中。否则，节头表的sh_info成员值为零。

               	PN_XNUM这被定义为0xffff，e_phnum可以具有的最大数字，指定程序头确切
               	的数目保存在哪里。

    e_shentsize		此成员保存每一个节头表大小（以字节为单位）。 节头是节头表中的一个
    项; 所有项的大小相同。

    e_shnum 	该成员保存节头表中的项数。因此 e_shentsize和e_shnum 的乘积给出了
    节头表的大小（以字节为单位）。如果文件节头表，e_shnum保持值为零。

    			如果段头表中的项数大于或等于 SHN_LORESERVE（0xff00），则 e_shnum
				保持值为零，节头表的实际项数包含在节头表中的 sh_size字段中。
				否则,节头表成员 sh_size 值为零。

	e_shstrndx		该成员保存与节名称字符串表相关联的项的节头表索引。如果文件没有
	节名称字符串表，则此成员值为 SHN_UNDEF 。

					如果节名字符串表的节索引大于或等于 SHN_LORESERVE ( 0xff00 ),则
					此成员值为 SHN_XINDEX ( 0xffff ),节名字符串表的实际节索引包含在
					节头中索引为 0 的 sh_link 字段中。否则,节头表的 sh_link 成员值
					为零。

					SHN_UNDEF 	此值标记未定义，缺失，无关或无意义的段引用。
                    例如，相对 SHN_UNDEF 而言“defined”符号是未定义的符号。

                    SHN_LORESERVE 	此值指定保留索引范围的下限。

                    SHN_LOPROC		大于或等于SHN_HIPROC的值被保留用于特定于处理器
                    的语义。

                    SHN_HIPROC小于或等于SHN_LOPROC的值被保留用于特定处理器的语义。

                    SHN_ABS       该值指定相应引用的绝对值。例如，相对于有绝对值节号 
                    SHN_ABS 定义的符号不受重定位影响。

                    SHN_COMMON		相对于本节定义的符号是常见的符号，例如
                    Fortran COMMON或未分配的C外部变量。

                    SHN_HIRESERVE 		此值指定 SHN_LORESERVE 与 SHN_HIRESERVE 
                    之间的保留索引范围的上限，这些值不引用节头表。那就是节头表不包含
                    保留索引的项。

	可执行或共享对象文件的程序头表是一个结构数组，每种结构都描述了系统准备程序执行所需的段或其他信息。目标文件段包含一个或多节。
	程序头只对可执行文件和共享对象文件有意义。文件通过ELF头的e_phentsize和e_phnum成员
	指定各自的程序头大小。 ELF文件程序头由类型 Elf32_Phdr 或 Elf64_Phdr 描述取决于
	架构：             

			typedef struct {
               uint32_t   p_type;
               Elf32_Off  p_offset;
               Elf32_Addr p_vaddr;
               Elf32_Addr p_paddr;
               uint32_t   p_filesz;
               uint32_t   p_memsz;
               uint32_t   p_flags;
               uint32_t   p_align;
           	} Elf32_Phdr;

           	typedef struct {
               uint32_t   p_type;
               uint32_t   p_flags;
               Elf64_Off  p_offset;
               Elf64_Addr p_vaddr;
               Elf64_Addr p_paddr;
               uint64_t   p_filesz;
               uint64_t   p_memsz;
               uint64_t   p_align;
           	} Elf64_Phdr;		

    32位和64位程序头之间最大的不同表现在 p_flag 成员处于结构的位置的不同。

    p_type 此数组元素描述的段类型或解释此数组元素的信息的方式。

            PT_NULL     未使用。没有定义成员值。使用此类型，程序头表可以包含忽略的项。

            PT_LOAD     数组元素指定由p_filesz和p_memsz描述的可加载段。文件中的字节会映射到内存段的起始位置。如果段的内存大小 (p_memsz) 大于文件大小 (p_filesz)，则将多余字节的值定义为 0。这些字节跟在段的已初始化区域后面。文件大小不能大于内存大小。程序头表中的可装入段的各项按升序显示，并基于 p_vaddr 成员进行排列。

            PT_DYNAMIC   指定动态链接信息。

            PT_INTERP   
            数组元素指定要作为解释程序调用的以空字符结尾的路径名的位置和大小。此段类型仅对可执行文件有意义（尽管共享对象可能出现这种情况）。但是此类型不能在一个文件中多次出现。此类型（如果存在）必须位于任何可装入段的各项的前面。

            PT_NOTE     数组元素指定辅助信息的位置和大小。

            PT_SHLIB    保留类型，但具有未指定的语义。

            PT_PHDR     数组元素指定程序头表在文件及程序内存映像中的位置和大小。此段类型不能在一个文件中多次出现。此外，仅当程序头表是程序内存映像的一部分时，才可以出现此段。此类型（如果存在）必须位于任何可装入段的各项的前面。

            PT_LOPROC   大于或等于PT_HIPROC的值保留用于特定于处理器的语义。

            PT_HIPROC   小于或等于PT_LOPROC的值被保留用于特定于处理器的语义。

            PT_GNU_STACK
                        GNU扩展，由Linux内核用于通过在 p_flags 成员中的标志集来控制堆栈的状态。

    p_offset      该成员指定相对段的第一个字节所在文件的起始位置的偏移。

    p_vaddr       该成员指定段的第一个字节在内存中的虚拟地址。

    p_paddr       在系统中该成员保留做段的物理地址。在 BSD 该成员不适用必须值为零。

    p_filesz      该字段指定段的文件映像中的字节数，可以为零。

    p_memsz     该段指定段的内存映像中的字节数，可以为零。

    p_flags     该字段指定与段相关的标志。

                PF_X   可执行段
                PF_W   可写段
                PF_R   可读段

                一个text段一般有PF_X 和 PF_R标志，一个数据段通常有PF_X, PF_W 以及 PF_R标志。

    p_align     可装入的进程段必须具有 p_vaddr 和 p_offset 的同余值（以页面大小为模数）。此成员可提供一个值，用于在内存和文件中根据该值对齐各段。值 0 和 1 表示无需对齐。另外，p_align 应为 2 的正整数幂，并且 p_vaddr 应等于 p_offset（以 p_align 为模数）。

    使用目标文件的节头表，可以定位文件的所有节。节头表是 Elf32_Shdr 或 Elf64_Shdr 结构的数组。ELF 头的 e_shoff 成员表示从文件的起始位置到节头表的字节偏移。e_shnum 成员表示节头表包含的项数。e_shentsize 成员表示每一项的大小（以字节为单位）。

    节头表索引是此数组的下标。一些节表头是保留的，如：初始化项和索引在SHN_LORESERVE 和 SHN_HIRESERVE 之间的节头表。初始项被用于扩展 ELF 头的 e_shnum 和 e_shstrndx 成员，符号表项的 st_shndx 成员，否则，初始项的 sh_size 成员值为零。保留的值不表示目标文件中的实际各节。

                SHN_UNDEF    未定义、缺少、无关或无意义的节引用。例如，已定义的与节数 SHN_UNDEF 有关的符号即是未定义符号。

                SHN_LORESERVE    所保留索引的范围的下边界。

                SHN_LOPROC    大于或等于SHN_HIPROC的值被保留用于特定于处理器的语义。

                SHN_HIPROC    小于或等于SHN_LOPROC的值被保留用于特定处理器的语义。

                SHN_ABS       此值指定相应引用的绝对值。例如，一个符号相对于段号SHN_ABS定义的绝对值不受重定位的影响。

                SHN_COMMON    已定义的与此节相关的符号为通用符号，如 FORTRAN COMMON 或未分配的 C 外部变量。这些符号有时称为暂定符号。

                SHN_HIRESERVE 所保留索引的范围的上边界。系统保留了 SHN_LORESERVE 和 SHN_HIRESERVE 之间的索引（包括这两个值）。这些值不会引用节头表。节头表不包含对应于所保留索引的项。

    节头表结构定义如下：

          typedef struct {
               uint32_t   sh_name;
               uint32_t   sh_type;
               uint32_t   sh_flags;
               Elf32_Addr sh_addr;
               Elf32_Off  sh_offset;
               uint32_t   sh_size;
               uint32_t   sh_link;
               uint32_t   sh_info;
               uint32_t   sh_addralign;
               uint32_t   sh_entsize;
           } Elf32_Shdr;

           typedef struct {
               uint32_t   sh_name;
               uint32_t   sh_type;
               uint64_t   sh_flags;
               Elf64_Addr sh_addr;
               Elf64_Off  sh_offset;
               uint64_t   sh_size;
               uint32_t   sh_link;
               uint32_t   sh_info;
               uint64_t   sh_addralign;
               uint64_t   sh_entsize;
           } Elf64_Shdr;

          32位和64位节头之间没有多少差异。

          sh_name   该成员指定节的名称。此成员值是节头字符串表的节索引，用于指定以空字符结尾的字符串的位置。

          sh_type   该成员用于将节的内容和语义分类。
                    SHT_NULL     将节头标识为非活动。此节头没有关联的节。节头的其他成员具有未定义的值。

                    SHT_PROGBITS   标识由程序定义的信息，这些信息的格式和含义仅由程序确定。

                    SHT_SYMTAB     标识符号表。通常，SHT_SYMTAB 节会提供用于链接编辑的符号。作为完整的符号表，该表可以包含许多对于动态链接不需要的符号。因此，目标文件还可以包含 SHT_DYNSYM 节。

                    SHT_STRTAB    标识字符串表。目标文件可以有多个字符串表节。

                    SHT_RELA      标识包含显式加数的重定位项，如 32 位类的目标文件的 Elf32_Rela 类型。目标文件可以有多个重定位节 

                    SHT_HASH    标识符号散列表。动态链接的目标文件必须包含符号散列表。当前，目标文件只能有一个散列表，但此限制在将来可能会放宽。  

                    SHT_DYNAMIC    标识动态链接的信息。当前，目标文件只能有一个动态节。

                    SHT_NOTE    标识以某种方法标记文件的信息。

                    SHT_NOBITS     标识在文件中不占用任何空间，但在其他方面与 SHT_PROGBITS 类似的节。虽然此节不包含任何字节，但 sh_offset 成员包含概念性文件偏移。

                    SHT_REL    标识不包含显式加数的重定位项，如 32 位类的目标文件的 Elf32_Rel 类型。目标文件可以有多个重定位节。

                    SHT_SHLIB     标识具有未指定的语义的保留节。

                    SHT_DYNSYM   SHT_DYNSYM节，其中包含一组尽可能少的动态链接符号，目标文件还可以包含SHT_SYMTAB节，从而可节省空间。 

                    SHT_LOPROC    大于等于此值 SHT_HIPROC 被保留用于处理器的语义保留。 

                    SHT_HIPROC  小于等于词值 SHT_LOPROC 被保留用于特定处理器的语义。

                    SHT_LOUSER  指定保留用于应用程序的索引范围的下边界。

                    SHT_HIUSER     指定保留用于应用程序的索引范围的上边界。应用程序可以使用 SHT_LOUSER 和 SHT_HIUSER 之间的节类型，而不会与当前或将来系统定义的节类型产生冲突。

    sh_flags    节可支持用于说明杂项属性的 1 位标志。如果在 sh_flags 中设置了标志位，则该节的此属性处于启用状态。否则，此属性处于禁用状态，或者不适用。未定义的属性会保留并设置为零。

                SHF_WRITE     本节包含在进程执行期间应该可写的数据。
                
                SHF_ALLOC      此节在进程执行期间占用内存。一些控制部分不驻留在
                                对象文件的内存映像。对于这些节，此属性处于禁用状态。

                SHF_EXECINSTR   本节包含可执行的机器指令。

                SHF_MASKPROC   此掩码中包含的所有位都保留用于特定处理器的语义。

    sh_addr     如果节显示在进程的内存映像中，则此成员会指定节的第一个字节所在的地址。否则，此成员值为零。

    sh_offset   从文件的起始位置到节中第一个字节的字节偏移。对于 SHT_NOBITS 节，此成员表示文件中的概念性偏移，因为该节在文件中不占用任何空间。

    sh_size     该成员指定节的大小（以字节为单位）。除非节类型为 SHT_NOBITS，否则该节将在文件中占用 sh_size 个字节。SHT_NOBITS 类型的节大小可以不为零，但该节在文件中不占用任何空间。

    sh_link     该成员指定节头表索引链接，其解释依赖于节类型。

    sh_info     该成员指定额外信息，其解释依赖于节类型。

    sh_addralign
                一些节具有地址对齐约束。例如，如果某节包含双字，则系统必须确保整个节双字对齐。在此情况下，sh_addr 的值在以 sh_addralign 的值为模数进行取模时，同余数必须等于 0。当前，仅允许使用 0 和 2 的正整数幂。值 0 和 1 表示节没有对齐约束。

    sh_entsize
              一些节包含固定大小的项的表，如符号表。对于这样的节，此成员会指定每一项的大小（以字节为单位）。如果节不包含固定大小的项的表，则此成员值为零。  

    包含程序和控制信息的各种节，下列各节由系统使用，并且具有指明的类型和属性：

    .bss      构成程序的内存映像的未初始化数据。根据定义，系统在程序开始运行时会将数据初始化为零。如节类型 SHT_NOBITS 所指明的那样，此节属性类型是SHF_ALLOC和SHF_WRITE。

    .comment  本节保存版本控制信息。此节类型是 SHT_PROGBITS。没有使用属性类型。

    .ctors    本节保存C ++构造函数的初始化指针。此节类型是 SHT_PROGBITS。属性类型是SHF_ALLOC和SHF_WRITE。

    .data     本节保存有助于程序内存映像的初始化数据。此节类型是 SHT_PROGBITS。属性类型是SHF_ALLOC和SHF_WRITE。

    .data1    本节保存有助于程序内存映像的初始化数据。此节类型是 SHT_PROGBITS。属性类型是SHF_ALLOC和SHF_WRITE。

    .debug    本节保存符号调试信息。内容未指定。此节类型是 SHT_PROGBITS。没有使用属性类型。

    dtors     本节保存C ++析构函数的初始化指针。此节类型是 SHT_PROGBITS。属性类型是SHF_ALLOC和SHF_WRITE

    .dynamic  本节保存动态链接信息。此节的属性将包括 SHF_ALLOC位。SHF_WRITE 位是否开启，与特定处理器相关。本节的类型是 SHT_DYNAMIC。属性之前已经说明。

    .dynstr   此节保存动态链接所需的字符串，最常见的是表示名称关联的字符串，带有符号表项。此节类型是 SHT_STRTAB。使用的属性类型是 SHF_ALLOC。

    .dynsym   本节保存动态链接符号表。本节的类型是 SHT_DYNSYM。使用的属性是 SHF_ALLOC。
    
    .fini     本节保存有助于进程终止代码的可执行指令。程序退出时通常系统会安排执行本节中的代码。本节的类型是 SHT_PROGBITS。使用的属性是 SHF_ALLOC 和 SHF_EXECINSTR 。

    .gnu.version
              本节保存版本符号表，ElfN_Half 元素数组。本节的类型是 SHT_GNU_versym。使用的属性类型是 SHF_ALLOC。

    .gnu.version_d
              本节保存版本符号定义，ElfN_Verdef 结构表。本节的类型是 SHT_GNU_verdef。使用的属性类型是 SHF_ALLOC。

    .gnu.version_r
               本节保存所需的版本符号元素，ElfN_Verneed结构表。本节的类型是 SHT_GNU_versym。使用的属性类型是 SHF_ALLOC。

    .got      本节保存全局偏移表。本节的类型是 SHT_PROGBITS。属性由处理器具体指定。

    .hash     本节包含一个符号哈希表。本节的类型是 SHT_HASH。使用的属性是 SHF_ALLOC。

    .init     本节包含有助于进程初始化代码的可执行指令。当一个程序开始运行，系统将在调用主程序之前执行本节中的代码。本节的类型是 SHT_PROGBITS。使用的属性是 SHF_ALLOC 和 SHF_EXECINSTR。

    .interp   本节保存程序解释器的路径名。如果文件具有包含本节的可加载段，本节属性将包括 SHF_ALLOC 位。否则，该位处于关闭状态。本节的类型是 SHT_PROGBITS。

    .line     本节保存符号调试的行号信息，其中描述了该对应关系程序源和机器代码。内容未指定。本节的类型是 SHT_PROGBITS。没有使用属性类型。

    .note     本节保存“提示节”格式的信息。此节类型为 SHT_NOTE。没有使用属性类型。 OpenBSD 机器可执行文件通常包含一个.note.openbsd.ident 节来标识自己，让内核在加载文件时绕过任何兼容性的ELF二进制仿真测试。

    .note.GNU-stack
              本节用于Linux对象文件中声明堆栈属性。 本节的类型是 SHT_PROGBITS。唯一使用的属性是 SHF_EXECINSTR。这向GNU链接器指示目标文件需要一个可执行堆栈。

    .plt     本节保存程序连接表。本节的类型是 SHT_PROGBITS。属性由处理器具体指定。

    .relNAME  本节的类型是 SHT_REL。保存如下所诉的重定位信息。如果文件具有包括重定位的可加载段，则此节的属性将包括 SHF_ALLOC 位。否则，该位会处于禁用状态。通常，name 由应用重定位的节提供。因此，.text 的重定位节的名称通常为 .rel.text 或 .rela.text。

    .relaNAME 本节的类型是 SHT_RELA。保存如下所诉的重定位信息。如果文件具有包括重定位的可加载段，则此节的属性将包括 SHF_ALLOC 位。否则，该位会处于禁用状态。通常，name 由应用重定位的节提供。因此，.text 的重定位节的名称通常为 .rel.text 或 .rela.text。

    .rodata   本节保存通常构成进程映像中的非可写段的只读数据。本节的类型是 SHT_PROGBITS。使用的属性是 SHF_ALLOC。

    .rodata1  本节保存通常构成进程映像中的非可写段的只读数据。本节的类型是 SHT_PROGBITS。使用的属性是 SHF_ALLOC。

    .shstrtab 本节保存节名称。本节的类型是 SHT_STRTAB。没有使用属性类型。

    .strtab   本节保存字符串，通常是表示与符号表各项关联的名称的字符串。如果文件具有包括符号字符串表的可装入段，则此节的属性将包括 SHF_ALLOC 位。否则，该位会处于禁用状态。本节的类型是 SHT_STRTAB。

    .symtab   本节保存符号表，如果文件具有包含符号表的可装入段，则此节的属性将包括 SHF_ALLOC 位。否则，该位会处于禁用状态。本节的类型是 SHT_SYMTAB

    .text     此节包含程序的“文本”或可执行指令。本节的类型是 SHT_PROGBITS。
                 使用的属性是 SHF_ALLOC 和 SHF_EXECINSTR。

    字符串表节保存的以'\0'结尾的字节，通常称为字符串。对象文件使用这些字符串来表示符号和节名称。一个引用一个字符串作为字符串节表的索引。
    第一个字节（其为索引为零）是一个空字节（'\ 0'）。类似地，字符串表的最后一个字节也是空字节，确保所有字符串的终止符号。

    目标文件的符号表包含查找和重新定位程序的符号定义所需的信息，符号表索引是这个数组的下标。

              typedef struct {
               uint32_t      st_name;
               Elf32_Addr    st_value;
               uint32_t      st_size;
               unsigned char st_info;
               unsigned char st_other;
               uint16_t      st_shndx;
              } Elf32_Sym;

              typedef struct {
               uint32_t      st_name;
               unsigned char st_info;
               unsigned char st_other;
               uint16_t      st_shndx;
               Elf64_Addr    st_value;
               uint64_t      st_size;
              } Elf64_Sym;

    32位和64位版本都有同样的成员，只是顺序不一样。

            st_name   此成员将目标文件的符号字符串表中的索引保存为字符表示符号名称。如果值为非零，则它表示给出符号名称的字符串表索引。 否则，符号表没有名字。

            st_value  该成员给出关联符号的值。

            st_size   许多符号具有相关联的大小。如果符号没有大小或未知的大小，该成员将保持为零。

            st_info   此成员指定符号的类型和绑定属性：
                      STT_NOTYPE  未定义符号的类型。

                      STT_OBJECT  符号与数据对象相关联。

                      STT_FUNC  该符号与一个函数或其他可执行代码相关联。

                      STT_SECTION 符号与段相关联。这种类型的符号表条目主要用于重定位。  通常具有 STB_LOCAL 绑定。

                      STT_FILE  通常，符号的名称会指定与目标文件关联的源文件的名称。文件符号具有 STB_LOCAL 绑定和节索引 SHN_ABS。此符号（如果存在）位于文件的其他 STB_LOCAL 符号前面。
  
                      STT_LOPROC  此值直到并包括 STT_HIPROC 为特定于处理器的语义保留。

                      STT_HIPROC  小于等于该值，保留用于特定于处理器的语义。

                      STB_LOCAL   局部符号。这些符号在包含其定义的目标文件的外部不可见。名称相同的局部符号可存在于多个文件中而不会相互干扰。

                      STB_GLOBAL  全局符号。这些符号对于合并的所有目标文件都可见。一个文件的全局符号定义满足另一个文件对相同全局符号的未定义引用。

                      STB_WEAK    弱符号。这些符号与全局符号类似，但其定义具有较低的优先级。

                      STB_LOPROC－STB_HIPROC
                                  此范围内包含的值保留用于特定于处理器的语义。

                      以下是一些包装和解包绑定和类型属性的宏：

                      ELF32_ST_BIND（info）或ELF64_ST_BIND（info）从 st_info 值中提取绑定。

                      ELF32_ST_TYPE（info）或ELF64_ST_TYPE（info） 从 st_info 值提取类型。

                      ELF32_ST_INFO(bind, type) or ELF64_ST_INFO(bind, type)将绑定和类型转换为 st_info 值。

            st_other  该成员定义符号可见性。
                      
                       STV_DEFAULT    默认符号可见性规则。
                       STV_INTERNAL   特定处理器的隐藏类。
                       STV_HIDDEN     符号在其他模块中不可用。
                       STV_PROTECTED  不可抢占，不导出。

                        下面是一些提取可见性类型的宏：

                        ELF32_ST_VISIBILITY(other) or ELF64_ST_VISIBILITY(other)

            st_shndx  所定义的每一个符号表项都与某节有关。此成员包含相关节头表索引。



            重新定位是使用符号定义连接符号引用的过程。 可重定位文件必须具有描述如何修改其部分内容的信息，从而允许可执行文件和共享对象文件保存
            流程程序映像的正确信息。重定位项是这些数据。

            不需要加法的重定位结构：

                  typedef struct {
                       Elf32_Addr r_offset;
                       uint32_t   r_info;
                   } Elf32_Rel;

                   typedef struct {
                       Elf64_Addr r_offset;
                       uint64_t   r_info;
                   } Elf64_Rel;

            需要加法的重定位结构：

                  typedef struct {
                       Elf32_Addr r_offset;
                       uint32_t   r_info;
                       int32_t    r_addend;
                  } Elf32_Rela;

                  typedef struct {
                       Elf64_Addr r_offset;
                       uint64_t   r_info;
                       int64_t    r_addend;
                  } Elf64_Rela;

             r_offset    此成员给出应用重定位操作的位置。对于可重定位文件，值为从该部分开始到由重定位影响的存储单元的字节偏移量。对于可执行文件或共享对象，该值是受重定位影响的存储单元的虚拟地址。

             r_info     此成员给出了必须进行重定位的符号表索引以及要应用的重定位类型。重定位类型处理器指定。当文本引用重定位条目的重定位类型或符号表索引时，
             它意味着分别将 ELF[32 | 64]_R_TYPE 或 ELF [32 | 64]_R_SYM 应用于项的 r_info 成员。

             r_addend   此成员指定用于计算要存储到可重定位字段中的值的常量加数。

            动态节包含一系列保存相关动态链接信息的结构。 d_tag成员控制d_un的解释。

                  typedef struct {
                       Elf32_Sword    d_tag;
                       union {
                           Elf32_Word d_val;
                           Elf32_Addr d_ptr;
                       } d_un;
                  } Elf32_Dyn;
                  extern Elf32_Dyn _DYNAMIC[];

                  typedef struct {
                       Elf64_Sxword    d_tag;
                       union {
                           Elf64_Xword d_val;
                           Elf64_Addr  d_ptr;
                       } d_un;
                  } Elf64_Dyn;
                  extern Elf64_Dyn _DYNAMIC[];

            d_tag此成员可能具有以下任何值：

                DT_NULL　标记动态部分的结尾

                　DT_NEEDED　将字符串表偏移到所需库的名称

                 DT_PLTRELSZ 　PLT relocs的字节大小

                 DT_PLTGOT 　PLT和/或GOT的地址

                 DT_HASH　　符号哈希表的地址

                 DT_STRTAB　　字符串表的地址

                 DT_SYMTAB　　符号表的地址

                 DT_RELA 　　Rela relocs表的地址

                 DT_RELASZ 　Rela表的字节大小

                 DT_RELAENT Rela表项的字节大小

                 DT_STRSZ　字符串表的字节大小

                 DT_SYMENT　符号表项的字节大小

                 DT_INIT　初始化函数的地址

                 DT_FINI　终止功能的地址

                 DT_SONAME　将字符串表偏移到共享对象的名称

                 DT_RPATH　字符串表偏移到库搜索路径（已弃用）

                 DT_SYMBOLIC　警报链接器在符号的可执行文件之前搜索此共享对象

                 Rel relocs　表的DT_REL地址

                 DT_RELSZ Rel表的字节大小

                 DT_RELENT Rel表条目的字节大小

                 DT_PLTREL PLT引用的reloc类型（Rela或Rel）

                 DT_DEBUG　未定义用于调试

                 DT_TEXTREL　没有这个表示不应该应用于非可写段

                 DT_JMPREL　仅用于PLT的reloc条目的地址

                 DT_BIND_NOW　在将控制权转移到可执行文件之前，指示动态链接器处理所有reloc

                 DT_RUNPATH　字符串表偏移到库搜索路径

                 DT_LOPROC　启动特定于处理器的语义

                 DT_HIPROC　处理器特定语义的结束

       d_val　　该成员表示具有各种解释的整数值。

      　d_ptr　　此成员表示程序虚拟地址。 当解释这些地址时，实际的地址应该是根据原始文件值和内存基址计算。 文件不包含修复这些地址的重定位项。

        _DYNAMIC　　包含.dynamic节中的所有动态结构的数组。 这是由链接器自动填充的。

说明
      ELF首先出现在　System V　中。ELF格式是　System V　中采用的标准。

      e_phnum，e_shnum和e_strndx的扩展是Linux扩展的。 Sun，BSD和AMD64也支持他们。有关更多信息，请参阅另见。

另见
      as(1), gdb(1), ld(1), objdump(1), execve(2), core(5)

      Hewlett-Packard，Elf-64对象文件格式。

      Santa Cruz Operation, System V 应用二进制接口。

      UNIX系统实验室，“对象文件”，可执行和链接格式（ELF）。

      Sun Microsystems，链接器和库指南。

      AMD64 ABI草案，系统V应用二进制接口AMD64架构处理器补充。

版权页标记
      该页面是Linux man-pages项目3.54版本的一部分。 项目描述及报告错误相关的信息，可以在http://www.kernel.org/doc/man-pages/找到。



Linux                                                       2013-04-17                                                      ELF(5)











